/**Filename: arrayList.c
 * Author(s): Vladimir Dudnic, Michael Groenier, Derek Fleener
 * Winter 2013 TCSS422
 * Project 2
 */

#include"arrayList.h"
#include<stdlib.h>
#include<string.h>

void list_grow(arrayList*);


int init_list(arrayList* list,int the_size){

  list->head = 0;
  list->tail = -1;
  list->size = 0;
  list->arraySize = the_size >= 1 ? the_size : 1;
  list->array = malloc(sizeof(void*) * list->arraySize);
  return 0;
}

void* list_get(arrayList* the_list, int the_index){
  void* item = 0;
  if(the_list->size > 0 && the_index < the_list->size && the_index >= 0 ){
    item = the_list->array[(the_list->head + the_index) % the_list->arraySize];
  }
  return item;
}

void* list_remove(arrayList* the_list, int the_index){
  void* item = 0;
  int act_index = 0;
  int i = 0;

  //if it is empty or they are asking for a non-existant index, just return 0
  if(the_list->size > 0 && the_index < the_list->size && the_index >= 0 ){

    act_index = (the_list->head + the_index) % the_list->arraySize;

    item = the_list->array[act_index];

    the_list->size--;


    if(the_list->size <= 0){
      //if we made the list empty or it was already empty, might as well just put the head/tail back to initial.
      the_list->head = 0;
      the_list->tail = -1;
      the_list->size = 0;

    } else {

      for(i = act_index;i != the_list->tail; i = (i+1) % the_list->arraySize){
        the_list->array[i] = the_list->array[(i+1) % the_list->arraySize];
      }
      the_list->tail = (the_list->tail - 1 + the_list->size) % the_list->size;
    }
  }

  return item;
}

int list_add(arrayList* the_list, void* the_item){
  int rv = 0;
  if(the_list->size == the_list->arraySize){
          list_grow(the_list);
  }

  the_list->tail = (the_list->tail + 1) % the_list->arraySize;

  the_list->array[the_list->tail] = the_item;
  the_list->size++;
  return rv;
}

void list_destroy(arrayList* the_list){
  free(the_list->array);
}


void list_destroyData(arrayList* the_list){
  int i = 0;
  for(i=0;i<the_list->size;i++){
    free(list_get(the_list, i));
  }
  free(the_list->array);
}

void list_grow(arrayList* the_list){
        int i = 0;
        int old_storeSize = the_list->arraySize;
        int items_ToMove = old_storeSize - the_list->head;
  int new_bytes = sizeof(void*) * the_list->arraySize * 2;

  the_list->array = realloc(the_list->array, new_bytes);

        the_list->arraySize *= 2;

        if(the_list->head > the_list->tail){
          //from head to the end of the old store.
          for(i = 0; i < items_ToMove; i++){
            the_list->array[the_list->head + old_storeSize + i] = the_list->array[the_list->head + i];
          }
          the_list->head += old_storeSize;
        }
}

